﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Csla
{
    /// <summary>
    /// TreeNode的集合
    /// 
    /// 里面的元素是贫血的树节点（ITreeNode：虽然有pid，却不一定有ParentNode对象。也就是说不一定有实体引用关系……）
    /// </summary>
    public interface ITreeNodeCollection : IList
    {
        /// <summary>
        /// 是深度排序还是广度排序
        /// </summary>
        TreeNodeTravelType SortType { get; set; }

        /// <summary>
        /// 是否集合中的TreeNode已经按照关系进行排序
        /// </summary>
        bool Sorted { get; }
        /// <summary>
        /// 是否集合中的Node都已经按照Pid关联了ParenNode和ChildrenNodes
        /// </summary>
        bool ObjectRelationsRuilt { get; }

        /// <summary>
        /// 重新建立ParenNode和ChildrenNodes关联
        /// </summary>
        void RebuildObjectRelations();
        /// <summary>
        /// 保证建立了ParenNode和ChildrenNodes关联
        /// </summary>
        void EnsureObjectRelations();

        /// <summary>
        /// 按照SortType进行排序
        /// </summary>
        void SortByTree();
        /// <summary>
        /// 保证已经排序
        /// </summary>
        void EnsureSorted();

        /// <summary>
        /// 把指定的节点升/降级
        /// </summary>
        /// <param name="node"></param>
        /// <param name="isUp"></param>
        void ChangeNodeLevel(ITreeNode node, bool isUp);
        /// <summary>
        /// 以指定的节点为位置标准，添加一个新的节点。
        /// </summary>
        /// <param name="targetNode">作为位置标准的节点</param>
        /// <param name="insertAsChild">新的节点是否是targetNode的孩子节点。（如果不是，就算兄弟/同级节点。）</param>
        /// <param name="createAsChild">
        /// 如果是添加兄弟节点，true表示放在targetNode的前面，false则表示放在后面。
        /// 如果是添加孩子节点，true表示新的节点作为第一个孩子，false表示作为第后一个绩点
        /// </param>
        /// <returns></returns>
        ITreeNode CreateNode(ITreeNode targetNode, bool createAsChild, bool beforeFirst);
        /// <summary>
        /// 把指定的节点和它所有的子节点都加入集合中。
        /// </summary>
        /// <param name="node"></param>
        void AddNode(ITreeNode node, bool recursivlyAddChildren);

        /// <summary>
        /// 在列表中查找前一个兄弟节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        ITreeNode FindPrevSibling(ITreeNode node);
        /// <summary>
        /// 在列表中查找后一个兄弟节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        ITreeNode FindNextSibling(ITreeNode node);
        /// <summary>
        /// 找“同级”的前/后一节点
        /// </summary>
        /// <param name="model"></param>
        /// <param name="before">找前一个还是后一个。</param>
        /// <returns></returns>
        ITreeNode FindNodeAtSameLevel(ITreeNode node, bool before);
        /// <summary>
        /// 查找所有根节点（没有父亲的节点）
        /// </summary>
        /// <returns></returns>
        ITreeNode[] FindRoots();

        ///// <summary>
        ///// 根据parent生成一个child。
        ///// 
        ///// （可能parent和child并不是一个类型。）
        ///// </summary>
        ///// <param name="parent"></param>
        ///// <returns></returns>
        //ITreeNode CreateChildInstance(ITreeNode parent);
        ///// <summary>
        ///// 前一节点
        ///// 
        ///// 含义：
        ///// 如果有父节点：
        /////     如果有前一兄弟节点，则返回它。
        /////     如果它就是父节点的第一个孩子，则返回父节点。
        ///// 没有父节点
        /////     如果这个节点就是list中的第一个根节点，返回null。
        /////     如果不是，则返回list中的前一个根节点。
        ///// </summary>
        ///// <param name="node"></param>
        ///// <returns></returns>
        //ITreeNode FindPrevNode(ITreeNode node);
        ///// <summary>
        ///// 后一节点
        ///// 
        ///// 含义：
        ///// 如果有父节点：
        /////     如果有后一兄弟节点，则返回它。
        /////     如果它就是父节点的最后一个孩子，则返回……………………………………
        ///// </summary>
        ///// <param name="node"></param>
        ///// <returns></returns>
        //ITreeNode FindNextNode(ITreeNode node);
        ///// <summary>
        ///// 寻找同级的前/后一节点。
        ///// 
        ///// 如果有父节点，则在兄弟节点中寻找。
        ///// 如果没有父节点，则node是根节点，直接在所有根节点中寻找。
        ///// </summary>
        ///// <param name="node"></param>
        ///// <param name="beforeNode">
        ///// true：找前一节点。
        ///// false：找后一节点。
        ///// </param>
        ///// <returns></returns>
        //ITreeNode FindVisualSibling(ITreeNode node, bool beforeNode);
        ///// <summary>
        ///// 寻找root的前一根节点
        ///// </summary>
        ///// <param name="root"></param>
        ///// <returns></returns>
        //ITreeNode FindPrevRoot(ITreeNode root);
        ///// <summary>
        ///// 寻找root的后一根节点
        ///// </summary>
        ///// <param name="root"></param>
        ///// <returns></returns>
        //ITreeNode FindNextRoot(ITreeNode root);
        ///// <summary>
        ///// 清除所有ParenNode和ChildrenNodes关联
        ///// </summary>
        //void ClearRelations();
        //void AddNode(ITreeNode node);
    }
    public interface ITreeNodeCollection<T> : ITreeNodeCollection, IList<T>
        where T : ITreeNode
    {
    }
}